package de.Objects;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.Texture;
import javax.media.j3d.Texture2D;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.image.TextureLoader;

public class Schneemann extends BranchGroup {

	Appearance kreis = null;
	Appearance zylinder = null;
	Appearance mund = null;
	Appearance augen = null;
	TransformGroup position = new TransformGroup();

	public TransformGroup getPosition() {
		return position;
	}

	public void setPosition(TransformGroup position) {
		this.position = position;
	}

	public Schneemann(int pNummer) {

		kreis = createAppearance("textures/snow1.jpg");
		mund = createAppearance("textures/rot-1.jpg");
		augen = createAppearance("textures/blau.jpg");

		if (pNummer != 1) {
			zylinder = createAppearance("textures/Gold.jpg");
		} else {
			zylinder = createAppearance("textures/1.jpg");
		}

		createKoerper();
		createArme();
		createHut();
		createAuge();
		createMund();
		createKnoepfe();
		createFinger();
		createNase();

		// this.compile();
	}

	private void createKnoepfe() {
		// translationKnopf
		createTransform(new Vector3f(0f, 2.2f, 0.75f), new Sphere(0.110f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));

		// translationKnopf1
		createTransform(new Vector3f(0f, 1.9f, 0.7f), new Sphere(0.110f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));

		// translationKnopf2
		createTransform(new Vector3f(0f, 2.5f, 0.7f), new Sphere(0.110f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));
	}

	private void createFinger() {
		// translationFingerRechts
		createArm(new Vector3f(-1.3f, 1.5f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), 0);

		// translationFingerRechts2
		double d = 135 * Math.PI / 180d;
		createArm(new Vector3f(-1.5f, 1.5f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), d);

		// translationFingerRechts3
		d = 135 * Math.PI / 270d;
		createArm(new Vector3f(-1.5f, 1.7f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), d);

		// translationFingerLinks
		d = 135 * Math.PI / 107d;
		createArm(new Vector3f(1.54f, 1.62f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), d);

		// translationFingerLinks2
		createArm(new Vector3f(1.33f, 1.6f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), 0);

		// translationFingerLinks3
		d = 135 * Math.PI / 90d;
		createArm(new Vector3f(1.56f, 1.82f, 0.0f), new Cylinder(.03f, .3f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund), d);
	}

	private void createNase() {
		Transform3D translationNase = new Transform3D();
		Transform3D rotationNase = new Transform3D();
		rotationNase.rotX(Math.toRadians(90));
		translationNase.mul(rotationNase);
		translationNase.setTranslation(new Vector3f(0f, 3.1f, 0.7f));
		TransformGroup transformNase = new TransformGroup(translationNase);
		addChild(transformNase);
		Appearance ap4 = new Appearance();
		ColoringAttributes col4 = new ColoringAttributes(
				new Color3f(1f, 0f, 0f), ColoringAttributes.NICEST);
		ap4.setColoringAttributes(col4);
		Cone nase = new Cone(.15f, 1f, ap4);// Nase
		transformNase.addChild(nase);
	}

	private void createKoerper() {
		// Oberkreis
		createTransform(new Vector3f(0.0f, 3.1f, 0.0f), new Sphere(0.6f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				kreis));
		// translationUnterleib
		createTransform(new Vector3f(0.0f, 2.2f, 0.0f), new Sphere(0.8f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				kreis));
		// translationMittelKreis
		createTransform(new Vector3f(0.0f, 1.0f, 0.0f), new Sphere(1.0f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				kreis));
	}

	private void createHut() {
		// translationCylinder
		createCylinder(new Vector3f(0f, 4.0f, 0.0f), new Cylinder(.40f, .70f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				zylinder));

		// translationCylinder2
		createCylinder(new Vector3f(0f, 3.6f, 0.0f), new Cylinder(.90f, .20f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				zylinder));
	}

	private void createArme() {
		double f = Math.sqrt(2) * 0.8f;
		double rotate = 135 * Math.PI / 180d;
		// createArmLinks
		createArm(new Vector3f(-1.0f, 2f, 0.0f), new Cylinder(0.065f,
				(float) f, Primitive.GENERATE_NORMALS
						| Primitive.GENERATE_TEXTURE_COORDS, mund), rotate);

		// createArmRechts
		rotate = 225 * Math.PI / 180d;
		createArm(new Vector3f(1.025f, 2.125f, 0.0f), new Cylinder(0.065f,
				(float) f, Primitive.GENERATE_NORMALS
						| Primitive.GENERATE_TEXTURE_COORDS, mund), rotate);
	}

	private void createAuge() {
		// translationAugeLinks
		createTransform(new Vector3f(-0.25f, 3.3f, 0.50f), new Sphere(0.1f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				augen));

		// translationAugeRechts
		createTransform(new Vector3f(0.2f, 3.3f, 0.50f), new Sphere(0.1f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				augen));
	}

	private void createMund() {
		// translationMund
		createTransform(new Vector3f(-0.3f, 2.96f, 0.49f), new Sphere(0.060f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));

		// translationMund1
		createTransform(new Vector3f(-0.1f, 2.90f, 0.52f), new Sphere(0.060f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));

		// translationMund2
		createTransform(new Vector3f(0.15f, 2.90f, 0.51f), new Sphere(0.060f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));

		// translationMund3
		createTransform(new Vector3f(0.35f, 2.96f, 0.45f), new Sphere(0.060f,
				Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
				mund));
	}

	private void createCylinder(Vector3f vec, Cylinder cylinder) {
		Transform3D translationArm = new Transform3D();
		translationArm.setTranslation(vec);

		TransformGroup transformArmGroup = new TransformGroup(translationArm);
		addChild(transformArmGroup);
		transformArmGroup.addChild(cylinder);
	}

	private void createArm(Vector3f vec, Cylinder cylinder, double rotate) {
		Transform3D translationArm = new Transform3D();
		Transform3D rotationX = new Transform3D();
		rotationX.rotZ(rotate);
		translationArm.mul(rotationX);
		translationArm.setTranslation(vec);

		TransformGroup transformArmGroup = new TransformGroup(translationArm);
		addChild(transformArmGroup);
		transformArmGroup.addChild(cylinder);
	}

	private void createTransform(Vector3f vec, Sphere sp) {
		Transform3D transform = new Transform3D();
		transform.setTranslation(vec);
		TransformGroup transformGroup = new TransformGroup(transform);
		addChild(transformGroup);
		transformGroup.addChild(sp);
	}

	private Appearance createAppearance(String image) {
		Appearance appearance = new Appearance();
		TextureLoader loaderTable = new TextureLoader(image, null);
		ImageComponent2D imageTable = loaderTable.getImage();
		if (imageTable == null) {
			System.out.println("failed loading texture");
		} else {
			Texture2D textTureTable = new Texture2D(Texture.BASE_LEVEL,
					Texture.RGBA, imageTable.getWidth(), imageTable.getHeight());
			textTureTable.setImage(0, imageTable);
			appearance.setTexture(textTureTable);
			TextureAttributes texAttrTable = new TextureAttributes();
			texAttrTable.setTextureMode(TextureAttributes.MODULATE);
			appearance.setTextureAttributes(texAttrTable);
		}
		return appearance;
	}
}